#!/usr/bin/python
# Copyright 2009 Alex K (wtwf.com) All rights reserved.

"""mythvideomv.py srcs destination
  move a video and keep the mythvideo database updated.

-c confile_file
  load myth config file
--cp
  copy video
-d
  debug output
--defaults
  output a mysql defaults file
"""

# latest version available http://wtwf.com/scripts/bin/expandRss
# documented somewhere around http://wtwf.com/scripts/

# TODO(ark) this http://www.osxfaq.com/rss/osxfaq.xml

import sys
import os
import traceback
import logging
import datetime
import time
import getopt
import MySQLdb

from xml.dom import minidom
import xml.sax.saxutils

if sys.version_info < (2, 4):
  raise 'You probably need python 2.5 or greater.'

def usage(code, msg=''):
  if code:
    fd = sys.stderr
  else:
    fd = sys.stdout
  PROGRAM = os.path.basename(sys.argv[0])
  print >> fd, __doc__ % locals()
  if msg:
    print >> fd, msg
  sys.exit(code)

def Main(args):
  logging.basicConfig()
  logging.getLogger().setLevel(logging.INFO)

  config_file = None
  cp = 'mythvideocp' in args[0]
  show_defaults = False

  try:
    opts, args = getopt.getopt(args[1:], 'c:dh',
                               ['config', 'cp', 'debug', 'defaults', 'help'])
  except getopt.error, msg:
    usage(1, msg)

  for opt, arg in opts:
    if opt in ('-c', '--config'):
      config_file = arg
    if opt in ('--cp',):
      cp = True
    if opt in ('-d', '--debug'):
      logging.getLogger().setLevel(logging.DEBUG)
      logging.debug('Set logging level to debug')
    if opt in ('--defaults',):
      show_defaults = True
    if opt in ('-h', '--help'):
      usage(0)

  if config_file is None:
    config_file = os.path.expanduser('~/.mythtv/config.xml')

  config = LoadConfig(config_file)

  if show_defaults:
    ShowDefaults(config)
    return

  srcs = args[0:-1]
  dst = args[-1]
  logging.debug('Sources: %s', ', '.join(srcs))
  logging.debug('Destination: %s', dst)

  # check destination exists
  if not (os.path.exists(dst) and os.path.isdir(dst)):
    logging.fatal('Destination "%s" is not a directory', dst)
    return

  logging.debug('Connecting to database')
  db = ConnectToDatabase(config)
  cursor = db.cursor()

  abs_dst = os.path.abspath(dst)

  for src in srcs:
    abs_src = os.path.abspath(src)
    UpdateMovie(abs_src, abs_dst, cp, cursor)

def LoadConfig(config_file):
  xmldoc = minidom.parseString('\n'.join(open(config_file)))
  config = {}

  for tag in ('DBHostName', 'DBUserName', 'DBPassword', 'DBName', 'DBPort'):
    config[tag] = str(xmldoc.getElementsByTagName(tag)[0].firstChild.data)
    logging.debug('Config: %s = %s', tag, config[tag])
  return config

def ShowDefaults(config):
  print '[client]'

  map = (('DBHostName', 'host'),
         ('DBName', 'database'),
         ('DBUserName', 'user'),
         ('DBPassword', 'password'))
  for tag, name in map:
    print '%s=%s' % (name, config[tag])
  # now port
  if int(config['DBPort']) > 0:
    print 'port=%d' % int(config['DBPort'])

def ConnectToDatabase(config):
  return MySQLdb.connect(host=config['DBHostName'],
                         db=config['DBName'],
                         user=config['DBUserName'],
                         passwd=config['DBPassword'])

def UpdateMovie(src, dst, cp, cursor):
  action = 'Moving'
  if cp:
    action = 'Copying'

  logging.debug('%s "%s" to "%s"', action, src, dst)

  dst = os.path.join(dst, os.path.basename(src))
  if os.path.exists(dst):
    logging.error("destination exists: %s", dst)
    return

  # check we can find the movie
  r = cursor.execute('SELECT intid, title, filename FROM videometadata '
                     'WHERE filename = %s',
                     src)
  rows = cursor.fetchall()

  if len(rows) != 1:
    logging.info('Unable to find: %s', src)

  intid = rows[0][0]

  logging.debug('intid is %r', intid)

  if os.path.islink(src):
    logging.debug('moving symlink')
    if cp:
      logging.error('COPYING NOT IMPLEMENTED %s Link!', action)
      return
    else:
      src_dst = os.readlink(src)
      os.remove(src)
      os.symlink(src_dst, dst)
      cursor.execute('UPDATE videometadata SET filename = %s WHERE intid = %s',
                     (dst, intid))
  else:
    if cp:
      logging.error('NOT IMPLEMENTED %s CP NON LINK!', action)
      return
    else:
      logging.debug('renaming non link')
      os.rename(src, dst)
      # now update the database
      cursor.execute('UPDATE videometadata SET filename = %s WHERE intid = %s',
                     (dst, intid))




if __name__ == '__main__':
  Main(sys.argv)
